home *** CD-ROM | disk | FTP | other *** search
/ STraTOS 1997 April & May / STraTOS 1 - 1997 April & May.iso / CD01 / INTERNET / SITES / GRAHAM / XA_6S.ZIP / SOURCE / FORMS.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-10-14  |  12.9 KB  |  531 lines

  1. /*
  2.  * XaAES - XaAES Ain't the AES
  3.  *
  4.  * A multitasking AES replacement for MiNT
  5.  *
  6.  */
  7.  
  8. #include <stdio.h>
  9. #include <string.h>
  10. #include "XA_DEFS.H"
  11. #include "XA_TYPES.H"
  12. #include "XA_GLOBL.H"
  13. #include "K_DEFS.H"
  14. #include "OBJECTS.H"
  15. #include "FRM_ALRT.H"
  16. #include "STD_WIDG.H"
  17. #include "C_WINDOW.H"
  18. #include "WATCHBOX.H"
  19. #include "FORM_DO.H"
  20.  
  21. #if 0
  22. #define CLIP(tree,obj,x,y,w,h)                \
  23.     object_abs_coords(tree, obj, &x, &y);    \
  24.     w = tree[obj].ob_width;                    \
  25.     h = tree[obj].ob_height;                \
  26.     set_clip(x, y, w, h);
  27. #endif
  28.  
  29. #define CLIP(tree,obj,x,y,w,h)    clear_clip()
  30. #define set_clip(x,y,w,h)        /* We don't want this now! */
  31.  
  32. #if 0
  33. #undef CLIP            /* Those set_clip(..) can't be useful */
  34. #endif
  35.  
  36. /*
  37.     FORM HANDLERS INTERFACE
  38. */
  39.  
  40. #if 0
  41. extern XA_WINDOW *window_list;        /* The global system window stack */
  42. #endif
  43.  
  44. /*
  45.     Primitive version of form_center....
  46.     -this ignores shadows & stuff
  47. */
  48. unsigned long XA_form_center(short clnt_pid, AESPB *pb)
  49. {
  50.     OBJECT *ob = pb->addrin[0];
  51.     short x, y, w, h;
  52.     
  53.     w = ob->ob_width;
  54.     h = ob->ob_height;
  55.     
  56.     x = (display.w - w) / 2;
  57.     y = (display.h - h) / 2;
  58.     
  59.     ob->ob_x = x;
  60.     ob->ob_y = y;
  61.     
  62.     pb->intout[0] = 1;
  63.     pb->intout[1] = x;
  64.     pb->intout[2] = y;
  65.     pb->intout[3] = w;
  66.     pb->intout[4] = h;
  67.     
  68.     return XAC_DONE;
  69. }
  70.  
  71. /*
  72.   Begin/end form handler
  73.   This is important - I hope most programs call this, as XaAES puts it's dialogs
  74.   in windows, and the windows are created here....
  75. */
  76. unsigned long XA_form_dial(short clnt_pid, AESPB *pb)
  77. {    
  78.     XA_CLIENT *client=Pid2Client(clnt_pid);
  79.     XA_WINDOW *dialog_window;
  80.     GRECT r;
  81.     short x, y, w, h;
  82.  
  83.     switch(pb->intin[0])
  84.     {
  85.         case FMD_START:             /* Create a window to put the dialog in */
  86.  
  87.             dialog_window = create_window(clnt_pid, 0, pb->intin[5], pb->intin[6], 
  88.                             pb->intin[7], pb->intin[8]);
  89.  
  90.             x = 2 * dialog_window->x - dialog_window->wx;
  91.             y = 2 * dialog_window->y - dialog_window->wy;
  92.             w = 2 * dialog_window->w - dialog_window->ww + 1;
  93.             h = 2 * dialog_window->h - dialog_window->wh + 1;
  94.  
  95.             delete_window(dialog_window);        /* Dispose of the temporary window we created */
  96.                                                 /* And create the real one. It stay's fixed until form_do is called */
  97.                                                 /* when it gets a MOVE property. */
  98. /* We create a window owned by the client so it will get button clicks for this area (in case it's gonna handle things it's own way) */
  99. #if PRESERVE_DIALOG_BGD
  100.             client->zen = dialog_window = create_window(clnt_pid, STORE_BACK | NO_MESSAGES | NO_WORK, x, y, w, h);
  101. #else
  102.             client->zen = dialog_window = create_window(clnt_pid, NO_WORK, x, y, w, h);
  103. #endif
  104.             dialog_window->is_open = TRUE;
  105.             dialog_window->created_by_FMD_START = TRUE;
  106. /* Set the window title to be the clients name to avoid confusion */
  107.             dialog_window->widgets[XAW_TITLE].stuff = (void*)client->name;
  108.  
  109.             v_hide_c(V_handle);
  110.             pull_wind_to_top(dialog_window);
  111.             display_window(dialog_window);
  112.             v_show_c(V_handle, 1);
  113.             
  114.             break;
  115.         case FMD_GROW:
  116.             break;
  117.         case FMD_SHRINK:
  118.             break;
  119.         case FMD_FINISH:        /* If the client's dialog window is still hanging around, dispose of it.... */
  120.             dialog_window = client->zen;
  121.             if (dialog_window)
  122.             {
  123.                 XA_WINDOW *wl=dialog_window->next;
  124.                 
  125.                 r.g_x=dialog_window->x;    r.g_y=dialog_window->y;
  126.                 r.g_w=dialog_window->w;    r.g_h=dialog_window->h;
  127.             
  128.                 clear_clip();
  129.                 client->zen = NULL;
  130.  
  131.                 dialog_window->is_open=FALSE;
  132.                 send_wind_to_bottom(dialog_window);
  133.                 delete_window(dialog_window);
  134.  
  135.                 v_hide_c(V_handle);
  136.                 display_windows_below(&r,wl);
  137.                 v_show_c(V_handle,1);
  138.     
  139.             }
  140.             break;
  141.     }
  142.     
  143.     pb->intout[0] = 1;
  144.     
  145.     return XAC_DONE;
  146. }
  147.  
  148. unsigned long XA_form_button(short clnt_pid, AESPB *pb)
  149. {
  150.     OBJECT *tree = (OBJECT*)pb->addrin[0];
  151.     short ob = pb->intin[0];
  152.     short is, os, x, y, w, h;
  153.  
  154.     pb->intout[1] = 0;
  155.  
  156.     if (tree[ob].ob_flags & EDITABLE)    /* Select a new editable text field? */
  157.     {
  158.     /*    
  159.      * Shouldn't this really do all that's done in form_do?
  160.      */
  161.  
  162.         pb->intout[1] = ob;
  163.     }
  164.  
  165.     if (((tree[ob].ob_flags & HIDETREE)        /* Was click on a valid selectable object? */
  166.         ||(tree[ob].ob_state & DISABLED))
  167.         ||(!(tree[ob].ob_flags & (SELECTABLE | EXIT | TOUCHEXIT))))
  168.     {
  169.         pb->intout[0] = 1;
  170.         return XAC_DONE;
  171.     }
  172.  
  173.     CLIP(tree, ob, x, y, w, h);
  174.  
  175.     os = tree[ob].ob_state;
  176.     is = os ^ SELECTED;
  177.  
  178.     if (tree[ob].ob_flags & TOUCHEXIT)        /* Change state & exit for TOUCHEXIT objects */
  179.     {
  180. /*
  181.  * Surely radio buttons must be handled as well?
  182.  */
  183.         /* Only selectable objects change appearance! */
  184.         if (tree[ob].ob_flags & SELECTABLE)
  185.         {
  186.             tree[ob].ob_state = is;
  187.             v_hide_c(V_handle);
  188.             draw_object_tree(tree, ob, MAX_DEPTH);
  189.             v_show_c(V_handle, 1);
  190.         }
  191.  
  192.         pb->intout[1] = ob;
  193.         
  194.         pb->intout[0] = 0;
  195.         
  196.         if (pb->intin[1] == 2)    /* Double click? */
  197.         {
  198.             pb->intout[1] |= 0x8000;
  199.         }
  200.         
  201.         return XAC_DONE;
  202.     }
  203.  
  204. /*
  205.  * Should this perhaps be done in watch_object()?
  206.  */
  207.     tree[ob].ob_state = is;
  208.     CLIP(tree, ob, x, y, w, h);
  209.     v_hide_c(V_handle);
  210.     draw_object_tree(tree, ob, MAX_DEPTH);
  211.     v_show_c(V_handle, 1);
  212.         
  213.     if (watch_object(tree, ob, is, os))        /* Do a watch to see if object is really selected */
  214.     {
  215.         if (!(tree[ob].ob_flags&SELECTABLE))
  216.         {
  217.             tree[ob].ob_state=os;
  218.             v_hide_c(V_handle);
  219.             draw_object_tree(tree,ob,2);
  220.             v_show_c(V_handle,1);
  221.         }
  222. /*
  223.  * Surely this should check for radio buttons?
  224.  */
  225.          if (tree[ob].ob_flags & EXIT)
  226.         {
  227.             pb->intout[1] = ob;
  228.             pb->intout[0] = 0;
  229. #ifdef CLIP
  230.             clear_clip();
  231. #endif
  232.             
  233.             return XAC_DONE;
  234.         }
  235.     }
  236.  
  237. #ifdef CLIP
  238.     clear_clip();
  239. #endif
  240.  
  241.     pb->intout[0] = 1;
  242.     return XAC_DONE;
  243.  
  244. unsigned long XA_form_alert(short clnt_pid, AESPB *pb)
  245. {
  246.     XA_CLIENT *client=Pid2Client(clnt_pid);
  247.     client->waiting_pb = pb;
  248.     
  249.     do_form_alert(pb->intin[0], (char*)pb->addrin[0], clnt_pid);
  250.  
  251.     return XAC_BLOCK;
  252. }
  253.  
  254. char error_alert[100];
  255. unsigned long XA_form_error(short clnt_pid, AESPB *pb)
  256. {
  257.     XA_CLIENT *client=Pid2Client(clnt_pid);
  258.     char *msg;
  259.     char icon;
  260.  
  261.     client->waiting_pb = pb;
  262.     
  263.     switch(pb->intin[0])
  264.     {
  265.         case 2:
  266.             msg = "File not found.";
  267.             icon = '5';
  268.             break;
  269.         case 3:
  270.             msg = "Path not found.";
  271.             icon = '5';
  272.             break;
  273.         case 4:
  274.             msg = "No more file handles.";
  275.             icon = '5';
  276.             break;
  277.         case 5:
  278.             msg = "Access denied.";
  279.             icon = '5';
  280.             break;
  281.         case 8:
  282.             msg = "Insufficient memory.";
  283.             icon = '6';
  284.             break;
  285.         case 10:
  286.             msg = "Invalid enviroment.";
  287.             icon = '6';
  288.             break;
  289.         case 11:
  290.             msg = "Invalid format.";
  291.             icon = '6';
  292.             break;
  293.         case 15:
  294.             msg = "Invalid drive specification.";
  295.             icon = '5';
  296.             break;
  297.         case 16:
  298.             msg = "Attempt to delete working directory.";
  299.             icon = '5';
  300.             break;
  301.         case 18:
  302.             msg = "No more files.";
  303.             icon = '5';
  304.             break;
  305.         default:
  306.             msg = "Unknown error.";
  307.             icon = '7';
  308.             break;
  309.         
  310.     }
  311.     
  312.     sprintf(error_alert, "[%c][ ERROR: | %s ][ Bugger ]", icon, msg);
  313.     
  314.     do_form_alert(1, error_alert, clnt_pid);
  315.  
  316.     return XAC_BLOCK;
  317. }
  318.  
  319. /*
  320.     Non-blocking form_do
  321.     - uses an object tree widget in a window to implement the form handler.
  322. */
  323. unsigned long XA_form_do(short clnt_pid, AESPB *pb)
  324. {
  325.     XA_CLIENT *client=Pid2Client(clnt_pid);
  326.     XA_WINDOW *dialog_window;
  327.     OBJECT *form = (OBJECT*)pb->addrin[0];
  328.     XA_WIDGET_LOCATION dialog_toolbar_loc = {LT, 3, 20};
  329.     short x, y, w, h;
  330.     short startedit;
  331.     
  332.     DIAGS(("form_do()\n"));
  333.  
  334.     client->waiting_pb = pb;
  335.     
  336.     if (!client->zen)            /* If the client hasn't called FMD_START (naughty), create a window for the dialog */
  337.     {
  338.         dialog_window = create_window(clnt_pid, 0, form->ob_x, form->ob_y, form->ob_width, form->ob_height);
  339.  
  340.         x = 2 * dialog_window->x - dialog_window->wx;
  341.         y = 2 * dialog_window->y - dialog_window->wy;
  342.         w = 2 * dialog_window->w - dialog_window->ww + 1;
  343.         h = 2 * dialog_window->h - dialog_window->wh + 1;
  344.  
  345.         delete_window(dialog_window);        /* Dispose of the temporary window we created */
  346.  
  347. #if PRESERVE_DIALOG_BGD
  348.         client->zen = dialog_window = create_window(clnt_pid, STORE_BACK | NO_MESSAGES | NO_WORK, x, y, w, h);
  349. #else
  350.         client->zen = dialog_window = create_window(clnt_pid, NO_MESSAGES | NO_WORK, x, y, w, h);
  351. #endif
  352.         dialog_window->created_by_FMD_START = FALSE;
  353.     /* Set the window title to be the clients name to avoid confusion */
  354.         dialog_window->widgets[XAW_TITLE].stuff = (void*)client->name;
  355.     }else{
  356.         dialog_window = client->zen;
  357.         dialog_window->owner = clnt_pid;
  358.         
  359.     }
  360.     
  361. //    client->waiting_for=XAWAIT_DIALOG|XAWAIT_KEY;
  362.     client->waiting_for=XAWAIT_DIALOG;
  363.     dialog_toolbar_loc.y = display.c_max_h + 10;
  364.     set_toolbar_widget(dialog_window, dialog_toolbar_loc, form);
  365.     
  366.     /*
  367.      * If there is an editable field, we'll need a keypress handler.
  368.      */
  369.     
  370.     startedit = pb->intin[0];
  371.     if (!startedit) {    /* If there's no set edit_obj field, search */
  372.         short f = 0;
  373.         do {
  374.             if (form[f].ob_flags & EDITABLE) {
  375.                 startedit = f;
  376.                 break;
  377.             }
  378.             f++;
  379.         } while (!(form[f].ob_flags & LASTOB));
  380.     }
  381.     
  382.     ((XA_WIDGET_TREE*)dialog_window->widgets[XAW_TOOLBAR].stuff)->owner = clnt_pid;
  383.     ((XA_WIDGET_TREE*)dialog_window->widgets[XAW_TOOLBAR].stuff)->edit_obj = startedit;
  384.     ((XA_WIDGET_TREE*)dialog_window->widgets[XAW_TOOLBAR].stuff)->edit_pos = 0;    /* Needed? */
  385.     
  386.     if (startedit) {    /* Set up keypress handler if needed */
  387.         TEDINFO *te = (TEDINFO*)form[startedit].ob_spec;
  388.         short f = 0;
  389.  
  390.         do {                                /* Ensure that there aren't two fields flagged as the */
  391.             form[f].ob_state &= ~IS_EDIT;        /* current edit field */
  392.             f++;
  393.         } while(!(form[f].ob_flags & LASTOB));
  394.         
  395.         dialog_window->keypress = &handle_form_key;
  396.         form[startedit].ob_state |= IS_EDIT;
  397.         te->te_tmplen = strlen(te->te_ptext);
  398.         ((XA_WIDGET_TREE*)dialog_window->widgets[XAW_TOOLBAR].stuff)->edit_pos = te->te_tmplen;
  399.  
  400.         CLIP(form, startedit, x, y, w, h);
  401.         v_hide_c(V_handle);
  402.         draw_object_tree(form, startedit, 2);
  403.         v_show_c(V_handle, 1);
  404.     }
  405.  
  406.     dialog_window->active_widgets |= (NO_MESSAGES | MOVE);    /* We don't want any redraw messages  */
  407.                                             /* - the widget handler will take care of it */
  408.     dialog_window->is_open = TRUE;
  409.  
  410. #if 0
  411.     v_hide_c(V_handle);
  412.     pull_wind_to_top(dialog_window);
  413.     display_window(dialog_window);
  414.     v_show_c(V_handle, 1);
  415. #endif
  416.  
  417.     return XAC_BLOCK;
  418. }
  419.  
  420. short XA_form_keybd(short clnt_pid, AESPB *pb)
  421. {
  422.     OBJECT *form = pb->addrin[0];
  423.     short ed_obj = pb->intin[0];
  424.     short keycode = pb->intin[1];
  425.     TEDINFO *ed_txt;
  426.     char *txt;
  427.     short o, x, y, w, h, last_ob;
  428.     
  429.     DIAGS(("form_keybd():%x,%x,%x\n", pb->intin[0], pb->intin[1], pb->intin[2]));
  430.     
  431.     pb->intout[0] = 1;
  432.     pb->intout[1] = ed_obj;
  433.     pb->intout[2] = 0;
  434.     
  435.     if (!(form[ed_obj].ob_flags & EDITABLE))
  436.         return XAC_DONE;
  437.  
  438.     ed_txt = (TEDINFO*)form[ed_obj].ob_spec;
  439.     txt = ed_txt->te_ptext;
  440.  
  441.     switch(keycode)
  442.     {
  443.     case 0x0f09:        /* TAB moves to next field */
  444.     case 0x5000:        /* DOWN ARROW also moves to next field */
  445.         if (form[ed_obj].ob_flags & LASTOB)    /* Loop round */
  446.             o = 0;
  447.         else
  448.             o = ed_obj;
  449.                 
  450.         for(o++; !(form[o].ob_flags & EDITABLE); o++)        /* search for next editable object */
  451.         {
  452.             if (form[o].ob_flags & LASTOB)    /* Loop round */
  453.                 o = 0;
  454.         }
  455.                 
  456.         break;
  457.     
  458.     case 0x5032:        /* SHIFT+DOWN ARROW moves to last field */
  459.         for(last_ob = 0; !(form[last_ob].ob_flags & LASTOB); last_ob++) ; /*find last object*/
  460.         o = last_ob;
  461.         for(; !(form[o].ob_flags & EDITABLE); o--) ;        /* search for last editable object */
  462.         break;
  463.             
  464.     case 0x4800:    /* UP ARROW moves to previous field */
  465.         for(last_ob = 0; !(form[last_ob].ob_flags & LASTOB); last_ob++) ; /*find last object*/
  466.                 
  467.         if (ed_obj == 1)    /* Loop round ? */
  468.             o = last_ob + 1;
  469.         else
  470.             o = ed_obj;
  471.                     
  472.         for(o--; !(form[o].ob_flags & EDITABLE); o--)        /* search for previous editable object */
  473.         {
  474.             if (o == 1)    /* Loop round */
  475.                 o = last_ob + 1;
  476.         }
  477.                 
  478.         break;
  479.     
  480.     case 0x4838:        /* SHIFT+UP ARROW moves to first field */
  481.         o = 0;
  482.         for(o++; !(form[o].ob_flags & EDITABLE); o++) ;    /* search for first editable object */
  483.         break;
  484.                     
  485.     case 0x1c0d:    /* Return - select default (if any) */
  486.         o = 0;
  487.         do{
  488.             if (form[o].ob_flags & DEFAULT)
  489.             {
  490.                 pb->intout[0] = 0;
  491.                 pb->intout[1] = o;
  492.                 return XAC_DONE;
  493.             }
  494.             o++;
  495.         } while(!(form[o].ob_flags & LASTOB));
  496.         break;
  497.                 
  498.     default:        /* just a plain key - insert character */
  499.         DIAGS(("passing character back to client\n"));
  500.         pb->intout[2] = keycode;
  501.         break;
  502.     }
  503.     switch(keycode) {    /* Moved from four places above. */
  504.     case 0x0f09:        /* All the common updating is */
  505.     case 0x5000:        /* done here now. */
  506.     case 0x5032:
  507.     case 0x4800:
  508.     case 0x4838:
  509.         if (o != ed_obj)    /* If edit field has changed, update the display */
  510.         {
  511.             form[o].ob_state |= IS_EDIT;
  512.             form[ed_obj].ob_state &= ~IS_EDIT;
  513.             
  514.             CLIP(form, ed_obj, x, y, w, h);
  515.             v_hide_c(V_handle);
  516.             draw_object_tree(form, ed_obj, 2);
  517.  
  518.             ((TEDINFO*)form[o].ob_spec)->te_tmplen = strlen(((TEDINFO*)form[o].ob_spec)->te_ptext);
  519.             
  520.             CLIP(form, o, x, y, w, h);
  521.             draw_object_tree(form, o, 2);
  522.             v_show_c(V_handle, 1);
  523.                 
  524.             pb->intout[1] = o;
  525.         }
  526.     }
  527.     
  528.     return XAC_DONE;
  529. }
  530.